﻿/*
    针对综合系统的用户人员和账号处理
 */
using Abp.Authorization.Users;
using Abp.Domain.Services;
using Abp.IdentityFramework;
using Abp.Runtime.Session;
using Abp.UI;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using SOEI.Solution.Authorization.Roles;
using SOEI.Solution.Helper;
using SOEI.Solution.Integratedes.Organization;
using SOEI.Solution.MultiTenancy;
using System;
using System.Linq;
using System.Threading.Tasks;
using static SOEI.Solution.AppCoreConst;

namespace SOEI.Solution.Authorization.Users
{
    public class UserPersonManager : DomainService
    {
        public IAbpSession AbpSession { get; set; }

        private readonly TenantManager _tenantManager;
        private readonly UserManager _userManager;
        private readonly RoleManager _roleManager;
        private readonly IPasswordHasher<User> _passwordHasher;


        public UserPersonManager(
            TenantManager tenantManager,
            UserManager userManager,
            RoleManager roleManager,
            IPasswordHasher<User> passwordHasher

        )
        {
            _tenantManager = tenantManager;
            _userManager = userManager;
            _roleManager = roleManager;
            _passwordHasher = passwordHasher;

            AbpSession = NullAbpSession.Instance;

        }

        private void CheckForTenant()
        {
            if (!AbpSession.TenantId.HasValue)
            {
                throw new InvalidOperationException("Can not register host users!");
            }
        }

        private async Task<Tenant> GetActiveTenantAsync()
        {
            if (!AbpSession.TenantId.HasValue)
            {
                return null;
            }

            return await GetActiveTenantAsync(AbpSession.TenantId.Value);
        }

        private async Task<Tenant> GetActiveTenantAsync(int tenantId)
        {
            var tenant = await _tenantManager.FindByIdAsync(tenantId);
            if (tenant == null)
            {
                throw new UserFriendlyException(L("UnknownTenantId{0}", tenantId));
            }

            if (!tenant.IsActive)
            {
                throw new UserFriendlyException(L("TenantIdIsNotActive{0}", tenantId));
            }

            return tenant;
        }

        protected virtual void CheckErrors(IdentityResult identityResult)
        {
            identityResult.CheckErrors(LocalizationManager);
        }

        #region  ====================================== 用户自定义 ==============================================

        /// <summary>
        /// 【华威扩展】 根据 OEconomyPerson 机构原始机构人员创建新的系统账号
        /// </summary>
        /// <returns></returns>
        public async Task CreateOrUpdateAccountAsync(OEconomyPerson OEconomyPerson)
        {
            if (string.IsNullOrEmpty(OEconomyPerson.LXDH))
            {
                throw new UserFriendlyException(string.Format("人员【{0}】的联系电话为空，无法创建系统账号！", OEconomyPerson.RYMC));
            }

            CheckForTenant();
            var tenant = await GetActiveTenantAsync();
            // 1. 验证手机号
            //this.CheckForPhoneNumber(OEconomyPerson.LXDH);

            // 本地系统中查找用户
            var user = await this._userManager.FindByNameAsync(OEconomyPerson.Id);

            if (user == null)
            {
                // 不存在创建新的
                user = EntityHelper.GetNewUserPerson(OEconomyPerson);
                user.SetNormalizedNames();
                foreach (var defaultRole in await _roleManager.Roles.Where(r => r.Name == AgencyRoleType.AgencyPerson).ToListAsync())
                {
                    user.Roles.Add(new UserRole(tenant.Id, user.Id, defaultRole.Id));
                }
                await _userManager.InitializeOptionsAsync(tenant.Id);
                CheckErrors(await _userManager.CreateAsync(user, OEconomyPerson.MM));
            }
            else
            {
                user.OriginalNumber = OEconomyPerson.JGBH; // 用户分配给机构
                await _userManager.UpdateAsync(user);
            }

            await CurrentUnitOfWork.SaveChangesAsync();
        }

        #endregion


        #region  ----------------------------辅助方法-------------------------------



        /// <summary>
        /// 检查手机号是否存在（已经存在抛出异常）
        /// </summary>
        /// <param name="PhoneNumber"></param>
        protected async void CheckForPhoneNumber(string PhoneNumber)
        {
            if (await this._userManager.IsExistPhoneNumberAsync(PhoneNumber))
            {
                throw new UserFriendlyException(string.Format("手机号码: {0} 已经被注册，请确认输入信息是否正确！", PhoneNumber));
            }
        }
        #endregion
    }
}
